package com.utils {

import fairygui.GComponent;

import laya.utils.Ease;
import laya.utils.Handler;
import laya.utils.Tween;

public class RotationUtils {

	/** 当前速度 */
	private var speed:Number;
	/** 加速度 */
	private var addSpeed:Number;
	/** 要被旋转的对象 */
	private var comp:GComponent;
	/** 总的角位移 */
	private var rotationTotal:Number;
	/** 最终停止的位置 */
	private var runEndIndex:Number;
	/** 旋转结束后调用函数 */
	private var endCall:Function;
	/** 转动开始消弱后调用函数 */
	private var proCall:Function;
	/** 缓动 */
	private var tween:Tween;

	/** 速度最大值 */
	public var maxSpeed:Number = 10;
	/** 减速后最小值 */
	public var minSpeed:Number = 0;
	/** 格子数量 */
	public var count:int = 20;
	/** 第一个奖区起始点与0点位置的偏移比例 */
	public var skew:Number = -0.5;
	/** 最少圈数 */
	public var minCircle:int = 5;
	/** 最多圈数 */
	public var maxCircle:int = 8;
	/** 指针所停位置离奖区边缘的比例 */
	public var offset:Number = 0.5;
	/** 旋转花费的时间，单位毫秒。 只有tween有用 */
	public var duration:Number = 1000 * 5;

	public function RotationUtils() {

	}

	/**
	 *
	 * @param comp 要旋转的对象
	 * @param runEndIndex 最终停止的位置
	 * @param callback 转动停止后调用函数
	 * @param proCall 转动开始消弱后调用函数
	 *
	 */
	public function rollFrame(comp:GComponent, runEndIndex:int, callback:Function, proCall:Function = null):void {
		roll(comp, runEndIndex, callback, proCall, true);
	}

	/**
	 *
	 * @param comp 要旋转的对象
	 * @param runEndIndex 最终停止的位置
	 * @param callback 转动停止后调用函数
	 * @param proCall 转动开始消弱后调用函数
	 *
	 */
	public function rollTween(comp:GComponent, runEndIndex:int, callback:Function, proCall:Function = null):void {
		roll(comp, runEndIndex, callback, proCall, false);
	}

	/**
	 *
	 * @param comp 要旋转的对象
	 * @param runEndIndex 最终停止的位置
	 * @param callback 转动停止后调用函数
	 * @param proCall 转动开始消弱后调用函数
	 *
	 */
	private function roll(comp:GComponent, runEndIndex:int, callback:Function, proCall:Function, isFrame:Boolean):void {
		this.comp = comp;
		this.endCall = callback;
		this.proCall = proCall;
		comp.rotation = comp.rotation % 360;//初始化角度

		this.runEndIndex = runEndIndex;
		rotationTotal = getRotationLong(count, skew, minCircle, maxCircle, runEndIndex, offset);//获取总长度
		if (isFrame) {
			rotationTotal -= comp.rotation;
			addSpeed = (maxSpeed * maxSpeed - minSpeed * minSpeed) / rotationTotal;//获取加速度
			speed = 0;//初始化速度
			Laya.timer.frameLoop(1, this, runHandler);
		} else {
			tween = Tween.to(comp, {
				rotation: rotationTotal,
				ease: Ease.expoInOut, complete: Handler.create(this, onRollEndHandler),
				update: new Handler(this, updateHandler)
			}, duration);

//				Ease.sineInOut
//				Ease.expoInOut
//				Ease.quadInOut
//				Ease.quartInOut
//				Ease.circInOut
//				Ease.cubicInOut

		}
	}

	private function updateHandler():void {
		var rt:Number = rotationTotal - rotationTotal / 3;
		if (rt <= comp.rotation) {
			if (proCall != null) proCall();
			proCall = null;
		}
	}

	private function onRollEndHandler():void {
		tween = null;
		if (endCall != null) endCall();
		endCall = null;
	}

	/**
	 * 获取总长度函数
	 * @param count 转盘拆分份数
	 * @param skew 第一个奖区起始点与0点位置的偏移比例
	 * @param Qmin 最少圈数
	 * @param Qmax 最多圈数
	 * @param location 奖品所在奖区
	 * @param offset 指针所停位置离奖区边缘的比例
	 * @return
	 *
	 */
	public function getRotationLong(count:int, skew:Number, Qmin:int, Qmax:int, location:int, offset:Number):Number {
		var _q:Number = 360 * (Math.floor(Math.random() * (Qmax - Qmin)) + Qmin);//整圈长度
		var _skew:Number = (360 / count) * skew;//第一个奖区起始点与0点位置的偏移量
		var _location:Number = (360 / count) * location;//目标奖区的起始点
		var _offset:Number = Math.floor(Math.random() * (360 / count) * (1 - 2 * offset)) + (360 / count) * offset;
		return _q + _skew + _location + _offset;
	}

	private function runHandler():void {
		//如果速度到达最大速度开始减速
		if (speed >= maxSpeed) {
			speed = 2 * maxSpeed - speed;//最大速度超范围后修正回来!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!关键
			addSpeed = -addSpeed;
			if (proCall != null) proCall();
			proCall = null;
		}

		speed += addSpeed;

		if (speed > 0) {
			comp.rotation += speed;
		} else {
			Laya.timer.clear(this, runHandler);
			onRollEndHandler();
		}
	}

	public function diapose():void {
		if (tween) tween.pause();
		tween = null;
		this.endCall = null;
		this.proCall = null;
		if (comp) Tween.clearAll(comp);
		Laya.timer.clear(this, runHandler);
	}

}

}